#include "link_test.h"

#include "dag.h"


#include <fstream>

using namespace dag;
using namespace std;


const char* LinkTest::description() {
	return "link_test";
}

bool LinkTest::run() {
	
	Link l1, l2, l3, l4;
	l1 = Link::fromRanges(2, 
						  1, 5, 2, 6,
						  9, 12, 7, 10);
	l2 = Link::fromConnections(9,
							   1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 
							   9, 7, 10, 8, 11, 9, 12, 10);

	l4 = Link::fullyConnected(10);
	if (l4.size() != 10) {
		return false;
	}
	for (size_t i = 0; i < 10; i++) {
		if (l4.forward(i) != i) {
			return false;
		}
		if (l4.reverse(i) != i) {
			return false;
		}
	}
	
	if (!equal_link(l1, l2)) {
		return false;
	}
	
	ofstream lofile("temp.link", ios::binary | ios::trunc | ios::out);
	if (!lofile.is_open()) {
		return false;
	}
	l2.serialize(lofile);
	lofile.close();
	
	ifstream lifile("temp.link", ios::binary | ios::in);
	if (!lifile.is_open()) {
		return false;
	}
	l3 = Link::inflate(lifile);
	lifile.close();
	
	if (!equal_link(l2, l3)) {
		return false;
	}
	
	
	l1.unlink(1, 2).unlink(2, 3).unlink(3, 4).unlink(4, 5).unlink(5, 6);
	if (equal_link(l1, l2)) {
		return false;
	}
	
	l2.unlinkRange(1, 5, 2, 6);
	if (!equal_link(l1, l2)) {
		return false;
	}
	
	l1.linkRange(0, 10, 0, 10);
	
	if (equal_link(l1, l2)) {
		return false;
	}
	
	l2.link(0, 0).link(1, 1).link(2, 2).link(3, 3).linkRange(4, 10, 4, 10);
	
	if (!equal_link(l1, l2)) {
		return false;
	}
	
	l1.clear();
	if (l1.size() != 0) {
		return false;
	}
	
	if (equal_link(l1, l2)) {
		return false;
	}
	
	l2.clear();
	if (!equal_link(l1, l2)) {
		return false;
	}
	
	l4 = Link::fullyConnected(10);
	size_t farray[10], rarray[10];
	l4.asArrays(farray, rarray);
	for (size_t i = 0; i < 10; i++) {
		if (farray[i] != i) {
			return false;
		}
		if (rarray[i] != i) {
			return false;
		}
	}
	
	l3 = Link::fromArrays(10, farray, rarray);
	if (!equal_link(l3, l4)) {
		return false;
	}
	
	return true;
}